import 'dart:math';

import 'package:flutter/material.dart';
import 'package:mybase/base/animate_do/types/animate_do_mixins.dart';
import 'package:mybase/base/animate_do/types/animate_do_types.dart';
import 'package:mybase/base/tool/FFMath/FFMath.dart';

// 旋转,可指定中心点
class FFSpin extends StatefulWidget {
  // 旋转的子组件
  final Widget child;

  // 旋转的时长
  final Duration duration;

  // 延迟
  final Duration delay;

  // 是否无限循环
  final bool infinite;

  // 旋转控制器
  final Function(AnimationController)? controller;

  // 是否手动触发
  final bool manualTrigger;

  // true:正向执行一次 false:反向执行一次
  final bool animate;

  // 动画结束回调
  final Function(AnimateDoDirection direction)? onFinish;

  // 旋转曲线
  final Curve curve;

  // 旋转角度 正数顺时针方向，负数逆时针方向
  final double angle;

  // 旋转中心 0，0代表原始的中心，（1，1）代表右下角
  AlignmentGeometry? alignment;

  // 旋转中心 0，0代表原始的中心，（50，0）代表中心点向右偏移50个单位
  Offset? origin;

  FFSpin(
      {key,
      required this.child,
      this.duration = const Duration(milliseconds: 1000),
      this.delay = const Duration(milliseconds: 0),
      this.infinite = false,
      this.controller,
      this.manualTrigger = false,
      this.animate = true,
      this.angle = 360,
      this.onFinish,
      this.alignment = Alignment.center,
      this.origin,
      this.curve = Curves.easeInOut})
      : super(key: key) {
    if (manualTrigger == true && controller == null) {
      throw FlutterError('If you want to use manualTrigger:true, \n\n'
          'Then you must provide the controller property, that is a callback like:\n\n'
          ' ( controller: AnimationController) => yourController = controller \n\n');
    }
  }

  @override
  FFSpinState createState() => FFSpinState();
}

/// State class, where the magic happens
class FFSpinState extends State<FFSpin>
    with SingleTickerProviderStateMixin, AnimateDoState {
  late Animation<double> spin;

  @override
  void dispose() {
    disposed = true;
    controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();

    controller = AnimationController(duration: widget.duration, vsync: this);

    spin = Tween<double>(begin: 0, end: widget.angle)
        .animate(CurvedAnimation(parent: controller, curve: widget.curve));

    /// Provided by the mixing [AnimateDoState] class
    configAnimation(
      delay: widget.delay,
      animate: widget.animate,
      manualTrigger: widget.manualTrigger,
      infinite: widget.infinite,
      onFinish: widget.onFinish,
      controllerCallback: widget.controller,
    );
  }

  @override
  Widget build(BuildContext context) {
    /// Provided by the mixing [AnimateDoState] class
    buildAnimation(
      delay: widget.delay,
      animate: widget.animate,
      manualTrigger: widget.manualTrigger,
      infinite: widget.infinite,
      onFinish: widget.onFinish,
      controllerCallback: widget.controller,
    );

    return AnimatedBuilder(
        animation: controller,
        builder: (BuildContext context, Widget? child) {
          return Transform.rotate(
            angle: FFMath.deg2rad(spin.value),
            child: widget.child,
            alignment: widget.alignment,
            origin: widget.origin,
          );
        });
  }
}
